import express from "express";
import crypto from "crypto";
import axios from "axios";
import querystring from "querystring";
import { TosClient } from "@volcengine/tos-sdk";

const router = express.Router();

// 签名函数
function sign(key, msg) {
  return crypto.createHmac("sha256", key).update(msg, "utf8").digest();
}

// 获取签名密钥
function getSignatureKey(key, dateStamp, regionName, serviceName) {
  const kDate = sign(Buffer.from(key, "utf8"), dateStamp);
  const kRegion = sign(kDate, regionName);
  const kService = sign(kRegion, serviceName);
  const kSigning = sign(kService, "request");
  return kSigning;
}

// 获取签名头
function getSignHeaders(
  method,
  service,
  host,
  region,
  request_parameters,
  access_key,
  secret_key
) {
  const contenttype = "application/x-www-form-urlencoded";
  const accept = "application/json";
  const t = new Date();
  const pad = (n) => n.toString().padStart(2, "0");
  const xdate =
    t.getUTCFullYear().toString() +
    pad(t.getUTCMonth() + 1) +
    pad(t.getUTCDate()) +
    "T" +
    pad(t.getUTCHours()) +
    pad(t.getUTCMinutes()) +
    pad(t.getUTCSeconds()) +
    "Z";
  const datestamp =
    t.getUTCFullYear().toString() +
    pad(t.getUTCMonth() + 1) +
    pad(t.getUTCDate());

  // 1. 拼接规范请求串
  const canonical_uri = "/";
  const canonical_querystring = request_parameters;
  const canonical_headers =
    "content-type:" +
    contenttype +
    "\n" +
    "host:" +
    host +
    "\n" +
    "x-date:" +
    xdate +
    "\n";
  const signed_headers = "content-type;host;x-date";
  const payload_hash = crypto.createHash("sha256").update("").digest("hex");
  const canonical_request =
    method +
    "\n" +
    canonical_uri +
    "\n" +
    canonical_querystring +
    "\n" +
    canonical_headers +
    "\n" +
    signed_headers +
    "\n" +
    payload_hash;

  // 2. 拼接待签名字符串
  const algorithm = "HMAC-SHA256";
  const credential_scope =
    datestamp + "/" + region + "/" + service + "/request";
  const string_to_sign =
    algorithm +
    "\n" +
    xdate +
    "\n" +
    credential_scope +
    "\n" +
    crypto.createHash("sha256").update(canonical_request, "utf8").digest("hex");

  // 3. 计算签名
  const signing_key = getSignatureKey(secret_key, datestamp, region, service);
  const signature = crypto
    .createHmac("sha256", signing_key)
    .update(string_to_sign, "utf8")
    .digest("hex");

  // 4. 添加签名到请求header中
  const authorization_header =
    algorithm +
    " " +
    "Credential=" +
    access_key +
    "/" +
    credential_scope +
    ", " +
    "SignedHeaders=" +
    signed_headers +
    ", " +
    "Signature=" +
    signature;

  const headers = {
    Accept: accept,
    "Content-Type": contenttype,
    "X-Date": xdate,
    Authorization: authorization_header,
  };
  return headers;
}

// ************* 发送请求获取临时AK/SK+Token **********************
const method = "GET";
const service = "sts";
const host = "open.volcengineapi.com";
//地域信息
const region = "cn-beijing";
const endpoint = "https://open.volcengineapi.com";
// 填写步骤一中创建的用户的 AK/SK 信息。
const access_key = "xxxxxxxxxxxxxxxx";
const secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==";
// 详细请求参数参考 https://www.volcengine.com/docs/6257/86374
const query_parameters = {
  Action: "AssumeRole",
  RoleSessionName: "fenghuawuque-updata",
  RoleTrn: "trn:iam::2110537085:role/fenghuawuque",
  Version: "2018-01-01",
};
const request_parameters = querystring.stringify(query_parameters);
const headers = getSignHeaders(
  method,
  service,
  host,
  region,
  request_parameters,
  access_key,
  secret_key
);
const request_url = endpoint + "?" + request_parameters;

console.log("Request URL = " + request_url);

async function getSTSdata() {
  try {
    const res = await axios.get(request_url, { headers });
    console.log("Response code: " + res.status);
    return res.data;
  } catch (err) {
    if (err.response) {
      console.log("Response code: " + err.response.status);
      console.log(err.response.data);
    } else {
      console.error(err);
    }
    return null;
  }
}

async function getSignature(bucket, key) {
  const STSdata = await getSTSdata();
  if (STSdata.Result.Credentials) {
    const client = new TosClient({
      accessKeyId: STSdata.Result.Credentials.AccessKeyId, // 从 STS 服务获取的临时访问密钥 AccessKey ID
      accessKeySecret: STSdata.Result.Credentials.SecretAccessKey, // 从 STS 服务获取的临时访问密钥 AccessKey Secret
      stsToken: STSdata.Result.Credentials.SessionToken, // 临时访问凭证
      region: "cn-beijing", // 例如 cn-beijing
      endpoint: "tos-cn-beijing.volces.com", // 例如 tos-cn-beijing.volces.com
    });

    const res = await client.preSignedPostSignature({
      bucket, // 例如 examplebucket
      key,
    });
    return res;
  }
}

router.get("/images", async (req, res) => {
  try {
    const key = req.query.key; // 从请求参数中获取 key
    const bucket = req.query.bucket; // 从请求参数中获取 bucket
    const result = await getSignature(bucket, key);
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Headers", "*");
    res.setHeader("Access-Control-Allow-Methods", "*");
    res.json(result);
  } catch (error) {
    console.error("Error generating signature:", error);
    res.status(500).send("Error generating signature");
  }
});

export default router;
